package com.light.netty.server.init;

import com.light.netty.server.handler.TcpBusinessHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @author fuhui
 * @Description：
 * @data 2025/3/13 11:10
 */
@Component
public class TcpNettyServerInit {

    private static final int PORT = 8083;
    private static final int THREAD_POOL_SIZE = 4;

    @PostConstruct
    public void init() throws Exception {
        System.out.println("初始化TCP服务端...........");
        Thread thread = new Thread(() -> {

// 1. 初始化线程组
            EventLoopGroup bossGroup = new NioEventLoopGroup(1);
            EventLoopGroup workerGroup = new NioEventLoopGroup(THREAD_POOL_SIZE);

            try {
                // 2. 创建 SSL 上下文
//            SslContext sslCtx = createSslContext();

                // 3. 配置 ServerBootstrap
                ServerBootstrap b = new ServerBootstrap();
                b.group(bossGroup, workerGroup)
                        .channel(NioServerSocketChannel.class) // 使用 NIO 模式
                        .option(ChannelOption.SO_BACKLOG, 1024) // 设置等待连接队列长度
                        .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT) // 显式设置缓冲池分配器，自定义字节缓冲区分配策略，优化内存管理。
//                        .childOption(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator()) // 接收缓冲区分配：动态管理接收缓冲区大小，提升吞吐量。
//                        .childOption(ChannelOption.MESSAGE_SIZE_ESTIMATOR, new DefaultMessageSizeEstimator(0)) // 需消息长度推断的场景：估算消息大小，用于流量控制或窗口扩展
                        .childOption(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000) // 连接建立超时：设置连接超时时间（毫秒）。
//                        .childOption(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(1024 * 10, 1024 * 30)) // 流控：控制写入缓冲区的高/低水位，防止内存溢出。
//                        .childOption(ChannelOption.ALLOW_HALF_CLOSURE, true) // 允许半关闭（一方关闭发送，另一方仍可接收）。
                        .childOption(ChannelOption.AUTO_READ, true) // 允许半关闭（一方关闭发送，另一方仍可接收）。
                        .childOption(ChannelOption.SO_KEEPALIVE, true) // 自动触发read()操作（默认开启）。启用TCP keepalive机制，检测连接状态。
                        .childOption(ChannelOption.TCP_NODELAY, true) // 禁用Nagle算法，减少延迟，提高实时性。
                        .childOption(ChannelOption.SO_REUSEADDR, true) // 允许端口复用，快速重启服务。
                        .childOption(ChannelOption.SO_LINGER, 5000) // 控制连接关闭时的延迟（毫秒）。
                        .childHandler(new ChannelInitializer<SocketChannel>() {
                            @Override
                            protected void initChannel(SocketChannel ch) throws Exception {
                                ChannelPipeline pipeline = ch.pipeline();

                                // 3.1 SSL 加密
//                            pipeline.addLast(sslCtx.newHandler(ch.alloc()));

                                // 心跳检测（30秒无活动自动断开）
                                pipeline.addLast(new IdleStateHandler(30, 0, 0));

                                // 日志记录
                                pipeline.addLast(new LoggingHandler(LogLevel.INFO));

                                // 协议编解码：自定义长度字段协议
//                                pipeline.addLast(new LengthFieldBasedFrameDecoder(1024*1024, 0, 4, 0, 4));
//                                pipeline.addLast(new LengthFieldPrepender(4));

                                // 添加分隔符解码器，使用DelimiterBasedFrameDecoder分隔符分隔
                                ByteBuf delimiter = Unpooled.copiedBuffer("\r\n".getBytes());
                                ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, delimiter));

                                // 入站解码
                                pipeline.addLast(new StringDecoder());
                                // 出站编码
                                pipeline.addLast(new StringEncoder());
                                // 业务处理器（提交到线程池）
                                pipeline.addLast(new TcpBusinessHandler());
                            }
                        });

                // 4. 绑定端口并启动
                ChannelFuture f = b.bind(PORT).sync();
                f.channel().closeFuture().sync();

            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                // 5. 释放资源
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            }
        });

        thread.setName("TCP Server-1");
        thread.start();
    }

//    private SslContext createSslContext() throws Exception {
//        // 加载密钥库
//        KeyStore ks = KeyStore.getInstance("JKS");
//        ks.load(new FileInputStream("server.keystore"), "password".toCharArray());
//
//        // 初始化密钥管理器
//        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
//        kmf.init(ks, "password".toCharArray());
//
//        // 初始化信任管理器
//        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
//        tmf.init(ks);
//        // 创建 SSL 上下文
//        return SslContextBuilder
//                .forServer(kmf)
//                .trustManager(tmf)
//                .build();
//    }
}